package servers;

import interfaces.SynchroServerInterface;
import util.TimeOut;





/**
 * Classe du serveur de synchronisation 
 *
 */
public class SynchroServer implements SynchroServerInterface  {
	
	/** le nom de la transition de synchronisation */
	public String name;
	
	/** le nombre de processus à synchroniser */
    public int nbProc ;

    /** compte le nombre de proceessus arrivés */
    public int cpt = 0;
    
    /** indique si la synchronisation est atteinte */
    public boolean synchroAtteinte;
    
    /** Objet de synchronisation */
    public static Object synchroObject = new Object();
    
    /** Valeur de temporisation lors d'une synchronisation */
    public static int TEMPO = 2000;
    
	/**
	 * Construecteur d'un gestionnaire de synchronisation	
	 * @param name
	 * @param nb_proc_in
	 */
	public SynchroServer(String name, int nb_proc_in) {
		this.nbProc = nb_proc_in; 
		this.name = name;
	}

	
	/**
	 * Méthode sur laquelle se synchronize les processus
	 * @throws InterruptedException 
	 */
	public boolean synchronize() throws InterruptedException {
	
		synchronized(synchroObject){
			if(cpt == 0){ // premier processu arrivé
				// tentative de synchronisation
				synchroAtteinte = false;
				// lancer la temporisation
				TimeOut timeOut = new TimeOut(TEMPO);
				timeOut.start();				
			}
			
			cpt++; // signaler son arrivée
			
			if(cpt < nbProc){ // attendre l'arrivée ds autres processus
				synchroObject.wait();
			}
			else{ // dernier processus à arriver
				// synchronisation réussie
				this.synchroAtteinte = true;
				// reveiller tous les processus bloqués
				synchroObject.notifyAll();
			}
			
			// Si les processus sont reveillés par le timeOut ou par le succès de la synchronisation
			if(cpt != 0)
				cpt = 0;
						
			return synchroAtteinte;
			
		}		
	}
}

